import json
import pickle
import base64
from django.shortcuts import render
from django.http import JsonResponse
# Create your views here.
from django.views import View

from apps.goods.models import SKU
from django_redis import get_redis_connection


class CartsView(View):
    """购物车管理"""

    def post(self, request):
        """添加购物车"""
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        count = data.get('count')
        selected = data.get('selected')
        # 验证参数

        # 验证商品
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '无此商品'})
        # 验证count
        # 将count类型转换
        try:
            count = int(count)
        except Exception:
            count = 1
        # 验证selected

        # 判断用户是否为登录状态
        user = request.user
        if user.is_authenticated:
            # True
            # 登录保存到redis
            redis_cli = get_redis_connection('carts')
            # 商品id 和数量
            redis_cli.hset('carts_%s' % user.id, sku_id, count)
            # 勾选
            redis_cli.sadd('selected_%s' % user.id, sku_id, )

            return JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            # False
            # 未登录设置session
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts:
                # 对加密的数据进行解密
                carts = pickle.loads(base64.b64decode(cookie_carts))
            else:
                carts = {}
                # 判断商品是否在购物车里
            if sku_id in carts:
                # 有则数量增加counts个
                counts = carts[sku_id]['count']
                count += counts
            carts[sku_id] = {
                'count': count,
                'selected': True
            }
            # 对字典进行加密
            base_bytes = base64.b64encode(pickle.dumps(carts))
            # 设置cookie
            reponse = JsonResponse({'code': 0, 'errmsg': 'ok'})
            reponse.set_cookie('carts', base_bytes.decode(), max_age=3600 * 24)
            return reponse

    def get(self, request):
        """购物车页面展示"""
        user = request.user
        if user.is_authenticated:
            # 链接redis
            redis_cli = get_redis_connection('carts')
            # hash 获取购物车中的数据
            # carts_counts = <class 'dict'>: {b'14': b'1', b'16': b'1', b'11': b'1'}
            carts_counts = redis_cli.hgetall('carts_%s' % user.id)
            # set  获取勾选状态
            selected_ids = redis_cli.smembers('selected_%s' % user.id)
            # 将redis数据转换为和cookie一样的数据
            # {sku_id:{count:xxx,selected:xxx}}
            carts = {}
            for sku_id, count in carts_counts.items():
                carts[int(sku_id)] = {
                    'count': int(count),
                    'selected': sku_id in selected_ids
                }
        else:
            # 未登录获取cookie
            cookie_carts = request.COOKIES.get('carts')
            if cookie_carts is not None:
                # 对加密的数据进行解密
                carts = pickle.loads(base64.b64decode(cookie_carts))
            else:
                carts = {}

        # 渲染界面
        sku_ids = carts.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        carts_list = []
        for sku in skus:
            carts_list.append({
                'id': sku.id,
                'name': sku.name,
                'count': int(carts[sku.id]['count']),
                'selected': str(carts.get(sku.id).get('selected')),  # 将True，转'True'，方便json解析
                'default_image_url': sku.default_image.url,
                'price': str(sku.price),  # 从Decimal('10.2')中取出'10.2'，方便json解析
                'amount': sku.price * int(carts[sku.id]['count'])
            })
        return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_skus': carts_list})

    def put(self, request):
        """修改购物车"""
        # 获取用户信息
        user = request.user
        # 接收数据
        data = json.loads(request.body.decode())
        count = data.get('count')
        sku_id = data.get('sku_id')
        selected = data.get('selected',True)

        # 验证参数
        if not all([sku_id, count]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})

        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 400, 'errmsg': '没有此商品'})

        try:
            count = int(count)
        except Exception:
            count = 1

        if user.is_authenticated:
            # 查询redis
            redis_cli = get_redis_connection('carts')
            # hash {user.id{sku_id:count}}
            redis_cli.hset('carts_%s' % user.id, sku_id, count)
            # set 是否勾选
            if selected:
                redis_cli.sadd('selected_%s' % user.id, sku_id)
            else:
                redis_cli.srem('selected_%s' % user.id, sku_id)

            return JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': {'count': count, 'selected': selected}})

        else:
            # 获取cookie
            carts_cookie = request.COOKIES.get('carts')
            if carts_cookie is not None:
                # 存在解密
                carts_dict = pickle.loads(base64.b64decode(carts_cookie))
            else:
                carts_dict = {}
            # 更新数据
            if sku_id in carts_dict:
                carts_dict[sku_id] = {
                    'count': count,
                    'selected': selected
                }
            # 加密
            new_carts = base64.b64encode(pickle.dumps(carts_dict))
            response = JsonResponse({'code': 0, 'errmsg': 'ok', 'cart_sku': {'count': count, 'selected': selected}})
            response.set_cookie('carts', new_carts.decode(), max_age=3600 * 24)
            return response

    def delete(self, request):
        """删除购物车"""
        data = json.loads(request.body.decode())
        sku_id = data.get('sku_id')
        try:
            SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return JsonResponse({'code': 0, 'errmsg': '没有此商品'})

        user = request.user
        if user.is_authenticated    :
            # 登录状态
            redis_cli = get_redis_connection('carts')
            redis_cli.hdel('carts_%s' % user.id, sku_id)
            redis_cli.srem('selected_%s' % user.id, sku_id)
            return JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            # 未登录状态
            cart_cookie = request.COOKIES.get('carts')
            if cart_cookie is not None:
                carts = pickle.loads(base64.b64decode(cart_cookie))
            else:
                carts = {}

            response = JsonResponse({'code': 0, 'errmsg': '删除成功'})

            if sku_id in carts:
                del carts[sku_id]  # 删除
                new_carts = base64.b64encode(pickle.dumps(carts))
                response.set_cookie('carts', new_carts.decode(), max_age=3600 * 24)
            return response


class CartsSelectedView(View):
    """全选"""
    def put(self, request):
        # 接收参数
        json_dict = json.loads(request.body.decode())
        selected = json_dict.get('selected',True)
        # 校验参数
        if selected:
            if not isinstance(selected, bool):
                return JsonResponse({'code': 400, 'errmsg': '参数有误'})

        # 判断用户是否登录
        user = request.user
        if user.is_authenticated:
            redis_cli = get_redis_connection('carts')
            # 获取所有购物车
            carts = redis_cli.hgetall('carts_%s' % user.id, )
            # 获取所有sku_id
            sku_id = carts.keys()
            if selected:
                redis_cli.sadd('selected_%s' % user.id, *sku_id)
            else:
                redis_cli.srem('selected_%s' % user.id, *sku_id)
            return JsonResponse({'code': 0, 'errmsg': 'ok'})
        else:
            # 非登录用户
            carts_cookie = request.COOKIES.get('carts')
            if carts_cookie:
                carts = pickle.loads(base64.b64decode(carts_cookie))
                for sku_id in carts:
                    carts[sku_id]['selected'] =selected
                new_carts=base64.b64encode(pickle.dumps(carts))
                reponse = JsonResponse({'code':0,'errmsg':'ok'})
                reponse.set_cookie('carts',new_carts.decode(),max_age=3600*24)
                return reponse



class CartsSimpieView(View):
    """我的购物车展示"""
    def get(self,request):
        user = request.user
        if user.is_authenticated:
            # 登录查询redis
            redis_cli = get_redis_connection('carts')
            #
            carts_dict=redis_cli.hgetall('carts_%s'%user.id,)
            selected_dict=redis_cli.smembers('selected_%s'%user.id)
            # 将redis数据组织成{sku_id{'count':1,'selected':True&false}}
            carts = {}
            for sku_id,count in carts_dict.items():
                carts[int(sku_id)]={
                    'count':int(count),
                    'selected':sku_id in selected_dict
                }
        else:
            # 未登录获取cookie
            carts_cookies = request.COOKIES.get('carts')
            if carts_cookies:
                # 解码
                carts=pickle.loads(base64.b64decode(carts_cookies))
            else:
                carts={}

        # 界面渲染
        carts_skus=[]
        sku_ids = carts.keys()
        skus = SKU.objects.filter(id__in=sku_ids)
        for sku in skus:
            carts_skus.append({
                'id':sku.id,
                'name': sku.name,
                'count': carts[sku.id]['count'],
                'default_image_url': sku.default_image.url

            })
        return JsonResponse({'code':0,'errmsg':'ok','cart_skus':carts_skus})
